#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <getopt.h>
#include <string.h>

#include "dnsclient.h"
#include "sock_utils.h"

static const char *progname;

static void
usage_help()
{
    fprintf(stderr, "usage: %s [ -a <domain name> ] [ -6 <ipv6 address> [ -c <cname record> ]\n", progname);
}

int main (int argc, char **argv)
{
    u_int16_t type;
    int optch;
    char *host;
    struct dc_addrinfo *addrs = NULL, *addr = NULL;

    progname = argv[0];

    while ((optch = getopt(argc, argv, "a:6:c:h")) != -1) {
	switch (optch) {
	    case 'a':
		type = DNS_T_A;
		host = strdup(optarg);
		break;
	    case '6':
		type = DNS_T_AAAA;
		host = strdup(optarg);
		break;
	    case 'c':
		type = DNS_T_CNAME;
		host = strdup(optarg);
		break;
	    case 'h':
		usage_help();
		exit(0);
	    default:
		usage_help();
		exit(1);
	}
    }

    if (!host || (argc < 2)) {
	usage_help();
	exit(1);
    }

    int udpsock;
    udpsock = create_udp_socket();
    if (udpsock == -1)
        exit(1);

    /* make udpsocket non blocking */
    if (make_socket_nonblocking(udpsock) == -1)
        error_msg("ERROR: Fail to make %d socket non blocking, using blocking socket\n");

    /* coonect socket to udp server */
    if ((connect_to_udp_server (udpsock, DEFAULT_SERVER, PORT)) == -1)
         exit(1);
    
    /* send generated dns query qbuffer to server */
    addrs = dns_client_query (host, type, udpsock);
    close(udpsock);
 
    for (addr = addrs; addr != NULL; addr = addr->ai_next) {
	if (addr->ai_family == AF_INET) {
	    struct sockaddr_in *sin;
	    char addr4[INET_ADDRSTRLEN];
    	    sin = ((struct sockaddr_in *) (addr->ai_addr));
    	    printf("Size: %2d, Addr: %s\n", addr->ai_addrlen, inet_ntop(addr->ai_family, &(sin->sin_addr.s_addr), addr4, addr->ai_addrlen));
	} else if (addr->ai_family == AF_INET6) {
	    struct sockaddr_in6 *sin6;
	    char addr6[INET6_ADDRSTRLEN];
    	    sin6 = ((struct sockaddr_in6 *) (addr->ai_addr));
    	    printf("Size: %2d, Addr: %s\n", addr->ai_addrlen, inet_ntop(addr->ai_family, sin6->sin6_addr.s6_addr32, addr6, addr->ai_addrlen));
	} 
    }

    free_addrinfo(&addrs);
    free(host);

    return 0;
}
